package ovt;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.log4j.Logger;

public class FileHandler {
	/**
	 * 供主逻辑调用的保存文件接口
	 * 
	 * @param dis
	 *            输入流
	 * @param path
	 *            要保存的文件路径
	 * @param size
	 *            要保存的文件的大小
	 * @throws IOException
	 */
	private Logger logger = Logger.getLogger(FileHandler.class);
	private ConfResolution conf = new ConfResolution();
	private static String xmlfilepath = ConfResolution.getServerXMLFilePath();
	private static String materialdirectory = new ConfResolution()
			.getMaterialDirectory();

	// private static String thumbnaildirectory = ConfResolution
	// .getThumbnailPath();

	public void readAndWrite0(ByteBuffer dis, String path, int size,
			SocketChannel sc) throws IOException {
		FileOutputStream os = getFileOS(path);
		readAndWrite(dis, os, size, sc);
		 os.close();
	}

	/**
	 * 具体的保存实现方法
	 * 
	 * @param dis
	 *            输入流
	 * @param os
	 *            写文件
	 * @param size
	 *            文件大小
	 * @throws IOException
	 */
	public ByteBuffer readAndWrite(ByteBuffer dis, FileOutputStream os,
			int size, SocketChannel sc) {
		try {
			byte[] buf = new byte[size];
			if (size > dis.limit() - dis.position()) {
				int savedlength = dis.limit() - dis.position();
				dis.get(buf, 0, savedlength);
				dis.clear();
				int a = 0;
				a = sc.read(dis);
				while (dis.position() == 0 ||(savedlength + a) < size) {
					dis.flip();
					dis.get(buf, savedlength, a);
					savedlength += a;
					dis.clear();
					a = sc.read(dis);
				}
				dis.flip();
				dis.get(buf, savedlength, size - savedlength);
			} else{
				dis.get(buf, 0, size);
			}
			os.write(buf);
			os.close();
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return dis;
	}

	/**
	 * 供保存接口调用
	 * 
	 * @param path
	 *            要保存的文件路径，文件不存在则创建文件
	 * @return fileoutputstream
	 * @throws IOException
	 */
	private FileOutputStream getFileOS(String path) throws IOException {
		File file = new File(path);
		if (!file.exists()) {
			file.createNewFile();
		}
		return new FileOutputStream(file);
	}

	public static boolean canCreateXMLFile(String filename) {
		boolean ismodified = false;
		xmlfilepath = ConfResolution.getServerXMLFilePath();
		HashMap<String, HashSet<String>> materiallast = new HashMap<String, HashSet<String>>();
		// 从XML文件中读取上次素材库的情况。
		boolean ret = XmlHandler.iterateWholeXMLToMaterial(xmlfilepath,
				materiallast);
		if (false == ret)
			return ismodified;
		HashMap<String, HashSet<String>> materialnow = new HashMap<String, HashSet<String>>();
		materialnow = iteratorAllMaterialFile(materialdirectory);
		if (materialnow.size() == 0)
			return ismodified;

		return ismodified;
	}

	/**
	 * @author windy.zhu 该函数供scanforchange类调用
	 * @param filename
	 *            要查看最后修改时间的文件夹
	 * @return filename文件夹的最后修改时间
	 */
	public static long getLastmodified_backup(String filename) {
		ArrayList<String> paths = new ArrayList<String>();
		HashSet<String> eligiblepath = new HashSet<String>();
		long lastmodified = 0L;
		File[] direcs = new File(filename).listFiles();
		for (File file : direcs) {
			paths.add(file.getAbsolutePath());
		}
		while (paths.size() > 0) {
			File[] subdirecs = new File(paths.get(0)).listFiles();
			boolean hassubdirecs = false;
			for (File file : subdirecs) {
				if (file.isDirectory()) {
					if (file.getName().contains("mask")) {
						eligiblepath.add(file.getAbsolutePath());
						continue;
					} else {
						paths.add(file.getAbsolutePath());
						hassubdirecs = true;
					}
				}
			}
			if (hassubdirecs == false) {
				eligiblepath.add(paths.get(0));
			}
			paths.remove(0);
		}
		Iterator<String> iter_eli = eligiblepath.iterator();
		while (iter_eli.hasNext()) {
			String filepath = iter_eli.next();
			if (new File(filepath).lastModified() > lastmodified) {
				lastmodified = new File(filepath).lastModified();
			}
		}
		return lastmodified;
	}

	/**
	 * 该函数供scanforchange类调用 查看文件的最后修改时间，包括object文件夹、Thumbnail文件夹以及mask文件夹
	 * 
	 * @param filename
	 * 
	 * @return filename文件夹的最后修改时间
	 */
	public static long getLastmodified(String filename) {
		long lastmodified = 0L;
		HashSet<String> objectdirectories = new HashSet<String>();
		HashSet<String> maskdirectories = new HashSet<String>();
		HashSet<String> thumbnaildirectories = new HashSet<String>();
		objectdirectories = getMaterialDirectory(
				ConfResolution.getMaterialDirectory(), "object");
		maskdirectories = getMaterialDirectory(
				ConfResolution.getMaterialDirectory(), "mask");
		thumbnaildirectories = getMaterialDirectory(
				ConfResolution.getMaterialDirectory(), "Thumbnail");
		Iterator<String> iter = objectdirectories.iterator();
		File file;
		while (iter.hasNext()) {
			file = new File(iter.next());
			if (file.lastModified() > lastmodified)
				lastmodified = file.lastModified();
		}
		iter = maskdirectories.iterator();
		while (iter.hasNext()) {
			file = new File(iter.next());
			if (file.lastModified() > lastmodified)
				lastmodified = file.lastModified();
		}
		iter = thumbnaildirectories.iterator();
		while (iter.hasNext()) {
			file = new File(iter.next());
			if (file.lastModified() > lastmodified)
				lastmodified = file.lastModified();
		}
		return lastmodified;
	}

	/**
	 * @author windy.zhu 取素材库的文件目录，不包含mask文件夹
	 * @param rootfolder
	 * @return
	 */
	public HashSet<String> getEigiblePath(String rootfolder) {
		File rootdirecs = new File(rootfolder);
		File[] direcs = rootdirecs.listFiles();
		ArrayList<String> paths = new ArrayList<String>();
		HashSet<String> eligiblepath = new HashSet<String>();
		for (File file : direcs) {
			paths.add(file.getAbsolutePath());
		}
		while (paths.size() > 0) {
			File[] subdirecs = new File(paths.get(0)).listFiles();
			boolean hassubdirecs = false;
			for (File file : subdirecs) {
				if (file.isDirectory()) {
					if (file.getName().contains("mask"))
						continue;
					else {
						paths.add(file.getAbsolutePath());
						hassubdirecs = true;
					}
				}
			}
			if (hassubdirecs == false) {
				eligiblepath.add(paths.get(0));
			}
			paths.remove(0);
		}
		return eligiblepath;
	}

	public static boolean deleteDirectory(String delpath) throws IOException {
		File file = new File(delpath);
		if (!file.exists())
			return true;
		String[] filelist = file.list();
		if (filelist == null) {
			file.delete();
			return true;
		}
		for (String filename : filelist) {
			File delfile = new File(delpath + "\\" + filename);
			if (!delfile.isDirectory())
				delfile.delete();
			else if (delfile.isDirectory())
				deleteDirectory(delpath + "\\" + filename);
		}
		file.delete();
		return true;
	}

	public static String getExtension(File file) {
		String extension = null;
		String filename = file.getName();
		extension = filename.substring(filename.lastIndexOf(".") + 1);
		return extension;
	}

	/**
	 * @param filepath
	 *            原素材文件的全路径
	 * @return
	 */
	public static boolean isMaskFileExist(String filepath) {
		boolean ret = false;
		HashSet<String> maskfileextension = new ConfResolution().getMaskType();
		// 计算mask文件路径，包含\\
		String maskfilepath = filepath.substring(0,
				filepath.lastIndexOf("\\") + 1) + "mask\\";
		// 计算素材文件的名字，纯名字
		String filename = filepath.substring(filepath.lastIndexOf("\\") + 1,
				filepath.lastIndexOf(".")) + "_mask";
		for (Iterator<String> i = maskfileextension.iterator(); i.hasNext();) {
			String suffix = "." + i.next();
			String maskfile = maskfilepath + filename + suffix;
			if (new File(maskfile).exists())
				ret = true;
		}
		return ret;
	}

	public static String findMaskFile(String filepath) {
		String ret = null;
		HashSet<String> maskfileextension = new ConfResolution().getMaskType();
		// 计算mask文件路径，包含\\
		String maskfilepath = filepath.substring(0,
				filepath.lastIndexOf("\\") + 1) + "mask\\";
		// 计算素材文件的名字，纯名字
		String filename = filepath.substring(filepath.lastIndexOf("\\") + 1,
				filepath.lastIndexOf(".")) + "_mask";
		for (Iterator<String> i = maskfileextension.iterator(); i.hasNext();) {
			String suffix = "." + i.next();
			String maskfile = maskfilepath + filename + suffix;
			if (new File(maskfile).exists())
				ret = maskfile;
		}
		return ret;
	}

	public static void copyFile(File sourceFile, File targetFile)
			throws IOException {
		// 新建文件输入流并对它进行缓冲
		FileInputStream input = new FileInputStream(sourceFile);
		BufferedInputStream inBuff = new BufferedInputStream(input);

		// 新建文件输出流并对它进行缓冲
		FileOutputStream output = new FileOutputStream(targetFile);
		BufferedOutputStream outBuff = new BufferedOutputStream(output);

		// 缓冲数组
		byte[] b = new byte[1024 * 5];
		int len;
		while ((len = inBuff.read(b)) != -1) {
			outBuff.write(b, 0, len);
		}
		// 刷新此缓冲的输出流
		outBuff.flush();

		// 关闭流
		inBuff.close();
		outBuff.close();
		output.close();
		input.close();
	}

	// 复制文件夹
	public static void copyDirectiory(String sourceDir, String targetDir)
			throws IOException {
		// 新建目标目录
		(new File(targetDir)).mkdirs();
		// 获取源文件夹当前下的文件或目录
		File[] file = (new File(sourceDir)).listFiles();
		for (int i = 0; i < file.length; i++) {
			if (file[i].isFile()) {
				// 源文件
				File sourceFile = file[i];
				// 目标文件
				File targetFile = new File(
						new File(targetDir).getAbsolutePath() + "\\"
								+ file[i].getName());
				copyFile(sourceFile, targetFile);
			}
			if (file[i].isDirectory()) {
				// 准备复制的源文件夹
				String dir1 = sourceDir + "\\" + file[i].getName();
				// 准备复制的目标文件夹
				String dir2 = targetDir + "\\" + file[i].getName();
				copyDirectiory(dir1, dir2);
			}
		}
	}

	public static boolean checkDirectoryValid(File file) {
		boolean isValid = true;
		File[] tempStrings = file.listFiles();
		HashSet<String> materialType = new ConfResolution().getMaterialType();
		HashSet<String> maskType = new ConfResolution().getMaskType();
		for (File subfile : tempStrings) {
			if (subfile.isFile()) {
				// 如果是文件的话
				String extension = getExtension(subfile);
				if (!materialType.contains(extension))
					return false;
			}
			if (subfile.isDirectory()) {
				// 如果是文件夹的话
				if (!subfile.getName().equals("mask"))
					return false;
				else {
					File[] maskfiles = subfile.listFiles();
					for (File maskfile : maskfiles) {
						String maskextension = getExtension(maskfile);
						if (!maskType.contains(maskextension))
							return false;
					}
				}
			}
		}
		return isValid;
	}

	/**
	 * @author windy.zhu 用于从文件中生成文件夹和文件集合对应的map
	 * @param filePath
	 * @return
	 */
	public static HashMap<String, HashSet<String>> iteratorAllMaterialFile(
			String filePath) {
		HashMap<String, HashSet<String>> hm = new HashMap<String, HashSet<String>>();
		File rootdirecs = new File(filePath);
		File[] direcs = rootdirecs.listFiles();
		ArrayList<String> paths = new ArrayList<String>();
		HashSet<String> eligiblepath = new HashSet<String>();
		for (File file : direcs) {
			paths.add(file.getAbsolutePath());
		}
		while (paths.size() > 0) {
			File[] subdirecs = new File(paths.get(0)).listFiles();
			boolean hassubdirecs = false;
			for (File file : subdirecs) {
				if (file.isDirectory()) {
					if (file.getName().contains("mask"))
						continue;
					else {
						paths.add(file.getAbsolutePath());
						hassubdirecs = true;
					}
				}
			}
			if (hassubdirecs == false) {
				eligiblepath.add(paths.get(0));
			}
			paths.remove(0);
		}
		Iterator<String> iter_eli = eligiblepath.iterator();

		while (iter_eli.hasNext()) {
			String materialdirectory = iter_eli.next();
			File file = new File(materialdirectory);
			String rootname = materialdirectory.substring(materialdirectory
					.indexOf(ConfResolution.getMaterialDirectory())
					+ ConfResolution.getMaterialDirectory().length());
			File[] meta_files = file.listFiles();
			HashSet<String> hstemp = new HashSet<String>();
			for (File filetemp : meta_files) {
				if (!filetemp.getName().startsWith("mask")) {
					hstemp.add(rootname + "\\" + filetemp.getName());
				}
			}
			hm.put(rootname, hstemp);
		}
		return hm;
	}

	/**
	 * @author windy.zhu 扫描当前素材库中的所有mask文件
	 * @param filepath
	 *            素材库路径 materialdirectory
	 * @param hm
	 *            key为素材类型，value为所有mask文件的hashset
	 * @return
	 */
	public static boolean iteratorAllMaskFile(String filepath,
			HashMap<String, HashSet<String>> hm) {
		boolean ret = true;
		File rootdirecs = new File(filepath);
		File[] direcs = rootdirecs.listFiles();
		ArrayList<String> paths = new ArrayList<String>();
		HashSet<String> eligiblepath = new HashSet<String>();
		for (File file : direcs) {
			paths.add(file.getAbsolutePath());
		}
		while (paths.size() > 0) {
			File[] subdirecs = new File(paths.get(0)).listFiles();
			boolean hassubdirecs = false;
			for (File file : subdirecs) {
				if (file.isDirectory()) {
					if (file.getName().contains("mask")) {
						continue;
					} else {
						paths.add(file.getAbsolutePath());
						hassubdirecs = true;
					}
				}
			}
			if (hassubdirecs == false) {
				eligiblepath.add(paths.get(0));
			}
			paths.remove(0);
		}
		Iterator<String> iter_eli = eligiblepath.iterator();

		while (iter_eli.hasNext()) {
			String maskdirectory = iter_eli.next();
			File file = new File(maskdirectory);
			String rootname = maskdirectory.substring(maskdirectory
					.indexOf(ConfResolution.getMaterialDirectory())
					+ ConfResolution.getMaterialDirectory().length());
			File[] meta_files = file.listFiles();
			HashSet<String> hstemp = new HashSet<String>();
			for (File filetemp : meta_files) {
				if (!filetemp.getName().startsWith("mask")) {
					hstemp.add(rootname + "\\" + filetemp.getName());
				}
			}
			hm.put(rootname, hstemp);
		}
		return ret;
	}

	/**
	 * @author windy.zhu 取得一个文件夹下的所有文件夹，包括嵌套文件夹；
	 * @param directory
	 */
	private static void getFileList(String directory,
			HashSet<String> directories) {

		// HashSet<String> hs = new HashSet<String>();
		// hs.add("mask");
		// hs.add("Thumbnail");
		// hs.add("object");
		//
		File f = new File(directory);
		File[] files = f.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (!files[i].isFile()) {
				directories.add(files[i].getAbsolutePath());
				getFileList(files[i].getAbsolutePath(), directories);
			}
		}
	}

	/**
	 * 得到所有素材目录
	 * 
	 * @param materiallib
	 * @return
	 */
	public static HashSet<String> getMaterialDirectory(String materiallib,
			String identifier) {
		HashSet<String> alldirectory = new HashSet<String>();
		getFileList(materiallib, alldirectory);
		if (alldirectory.size() == 0 || alldirectory == null)
			return null;
		HashSet<String> hs = new HashSet<String>();
		hs.add("mask");
		hs.add("object");
		hs.add("thumbnail");
		HashSet<String> ret = new HashSet<String>();
		Iterator<String> iter = alldirectory.iterator();
		while (iter.hasNext()) {// 过滤文件夹，找到标准素材文件夹
			String directory = iter.next();
			// System.out.println("目录 "+directory+" 共有文件 "+new
			// File(directory).listFiles().length+" 个");
			if (new File(directory).listFiles().length != 3)
				continue;
			File[] files = new File(directory).listFiles();
			boolean isright = true;
			for (File temp : files) {
				String name = temp.getName().toLowerCase();
				if (!hs.contains(name))
					isright = false;
			}
			if (true == isright) {
				ret.add(new File(directory).getAbsolutePath() + "\\"
						+ identifier);
			}
		}
		// print(ret);
		return ret;
	}

	public static void print(HashSet<String> hs) {
		Iterator<String> iter = hs.iterator();
		while (iter.hasNext()) {
			System.out.println(iter.next());
		}
	}

	/**
	 * 检测一个素材文件的mask和缩略图是否都存在。
	 * 
	 * @param materialpath
	 *            素材文件的路径
	 * @return
	 */
	public static boolean isMaterialValid(String materialpath) {
		boolean ret = false;
		if ((!new File(materialpath).exists()) || materialpath == null)
			return ret;
		boolean ismaskvalid = false;
		// D:\Workspace\CheckSocket\images\decorator\glasses\object\1.jpg
		String materialname = materialpath.substring(
				materialpath.lastIndexOf("\\") + 1,
				materialpath.lastIndexOf("."));// 1
		String maskdirectory = new File(materialpath).getParentFile()
				.getParentFile().getAbsolutePath()
				+ "\\mask\\";// D:\Workspace\CheckSocket\images\decorator\glasses\mask\
		String thumbnailname = new File(materialpath).getParentFile()
				.getParentFile().getAbsolutePath()
				+ "\\Thumbnail\\" + materialname + ".png";// D:\Workspace\CheckSocket\images\decorator\glasses\Thumbnail\1.png
		HashSet<String> masktype = ConfResolution.getMaskType();
		Iterator<String> iter = masktype.iterator();
		while (iter.hasNext()) {
			String temp = iter.next();
			if (new File(maskdirectory + materialname + "_mask." + temp)
					.exists()) {
				ismaskvalid = true;
				break;
			}
		}
		if (ismaskvalid == true && new File(thumbnailname).exists())
			ret = true;

		return ret;
	}

	public static boolean isThumbnailValid(String thumbnailpath) {
		boolean ret = false;
		if ((!new File(thumbnailpath).exists()) || thumbnailpath == null)
			return ret;
		// D:\Workspace\CheckSocket\images\decorator\glasses\Thumbnail\1.png
		String filename = thumbnailpath.substring(
				thumbnailpath.lastIndexOf("\\") + 1,
				thumbnailpath.lastIndexOf("."));
		boolean ismaskvalid = false;
		boolean ismaterialvalid = false;
		HashSet<String> masktype = ConfResolution.getMaskType();
		HashSet<String> materialtype = ConfResolution.getMaterialType();
		String maskdirectory = new File(thumbnailpath).getParentFile()
				.getParentFile().getAbsolutePath()
				+ "\\mask\\";
		String materialdirec = new File(thumbnailpath).getParentFile()
				.getParentFile().getAbsolutePath()
				+ "\\object\\";
		Iterator<String> iter = masktype.iterator();
		while (iter.hasNext()) {
			if (new File(maskdirectory + filename + "_mask." + iter.next())
					.exists())
				ismaskvalid = true;
		}

		iter = materialtype.iterator();
		while (iter.hasNext()) {
			if (new File(materialdirec + filename + "." + iter.next()).exists())
				ismaterialvalid = true;
		}

		if (ismaskvalid == true && ismaterialvalid == true)
			ret = true;
		return ret;
	}

	public static String getCreateTimeOfFile(String filename) {
		String getTime = null;
		try {
			Process p = Runtime.getRuntime().exec("cmd /C dir d:\\ /tc");

			InputStream is = p.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String result;
			while ((result = br.readLine()) != null) {
				String[] str = result.split(" ");
				for (int i = str.length - 1; i >= 0; i--) {
					if (str[i].equals("update.xml")) {
						getTime = str[0] + " " + str[2];
					}
				}
			}
			System.out.println("modifyInfoLoade.log 文件的创建日期是：" + getTime);
		} catch (java.io.IOException exc) {
			exc.printStackTrace();
		}
		return getTime;
	}

	public static void gettime() {
		try {
			Process p = Runtime.getRuntime().exec(
					"cmd /C dir d://update.xml /tc");
			InputStream is = p.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			StringBuffer sb = new StringBuffer();
			String str;
			int i = 0;
			while ((str = br.readLine()) != null) {
				i++;
				if (i == 6) {
					System.out.println(str.substring(0, 17));
				}
			}

		} catch (java.io.IOException exc) {
			exc.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// System.out.println(getLastmodified(ConfResolution.getMaterialDirectory()));
		// System.out.println(isThumbnailValid("D:\\Workspace\\CheckSocket\\images\\pip\\Thumbnail\\159_153_526_413_-1_-1.png"));
		// gettime();
		try {
			copyFile(new File("D:\\update.xml"), new File(
					"D:\\client\\update1.xml"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
